package com.gmrz.uaf.crypto.internal.algos;

import java.security.*;
import java.util.Set;

import com.gmrz.util.Convert;
import com.google.inject.Inject;
import com.gmrz.uaf.crypto.CryptoConstants;
import com.gmrz.uaf.crypto.CryptoEngine;
import com.gmrz.uaf.crypto.spi.UAFAuthAlgorithmSuite;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class UAFAuthAlg implements UAFAuthAlgorithmSuite {
    private static final Logger logger = LogManager.getLogger(UAFAuthAlg.class);
    protected CryptoConstants.UAFAlgSign authAlgorithmSuite = null;
    protected CryptoEngine cryptoEngine = null;

    public int getSuite() {
        return this.authAlgorithmSuite.getSuite();
    }

    public String getName() {
        return this.authAlgorithmSuite.getName();
    }

    public String getHashingAlgo() {
        return this.authAlgorithmSuite.getHashingAlgo();
    }

    public UAFAuthAlg(CryptoConstants.UAFAlgSign authAlgorithmSuite) {
        this.authAlgorithmSuite = authAlgorithmSuite;
    }

    @Inject
    public void setCryptoEngine(CryptoEngine cryptoEngine) {
        this.cryptoEngine = cryptoEngine;
    }

    public boolean verifySignature(PublicKey publicKey, byte[] signedData, byte[] signature)
            throws GeneralSecurityException {
        logger.info("UAFAuthAlg verifySignature start");
        long start = System.currentTimeMillis();
        // Signature 类用来为应用程序提供数字签名算法功能。数字签名用于确保数字数据的验证和完整性。
        Signature sig = null;
        logger.debug("Suite:"+this.authAlgorithmSuite.getSuite()+",SignatureAlgo:"+this.authAlgorithmSuite.getSignatureAlgo());
        if(10 == this.authAlgorithmSuite.getSuite()){
//            Set<String> sets = Security.getAlgorithms("Signature");
//            for(String str : sets){
//                if(str.contains("RSA")){
//                    Signature s = Signature.getInstance(str);
//                    logger.debug(s.getAlgorithm()+"-->"+s.getProvider().getName());
//                }
//            }
            // 使用指定签名算法、签名对象提供者生成签名对象
            sig = Signature.getInstance(this.authAlgorithmSuite.getSignatureAlgo(),"BC");
        }else {
            sig = Signature.getInstance(this.authAlgorithmSuite.getSignatureAlgo());
        }
        // 使用公钥初始化签名对象进行验证
        sig.initVerify(publicKey);
        // 使用指定的 byte 数组更新要签名的数据。
        sig.update(signedData);
        logger.debug("UAFAuthAlg verifySignature time:" + (System.currentTimeMillis() - start) + " ms");
        // 验证签名，signature：签名
        return sig.verify(signature);
    }

    public byte[] hash(byte[] data) throws GeneralSecurityException {
        MessageDigest digest = MessageDigest.getInstance(this.authAlgorithmSuite.getHashingAlgo());

        if (digest != null) {
            return digest.digest(data);
        }

        return null;
    }

    public boolean init() {
        //return true;//Security.getAlgorithms("Signature").contains(this.authAlgorithmSuite.getSignatureAlgo());
        Signature sig = null;
        try {
            sig = Signature.getInstance(this.authAlgorithmSuite.getSignatureAlgo());
        } catch (NoSuchAlgorithmException e) {

        }
        if (null != sig) {
            return true;
        }
        return false;
    }
}
